import IconFont from '@/IconFontAl';
import defPic from '@/assets/imgs/default_head.png';
import { useLayoutUpdateEffect } from '@/utils/hooks/useLayoutUpdateEffect';
import { DoubleRightOutlined } from '@ant-design/icons';
import { Input } from 'antd';
import classNames from 'classnames';
import { cloneDeep } from 'lodash-es';
import React, {
  forwardRef,
  useCallback,
  useEffect,
  useImperativeHandle,
  useMemo,
  useRef,
  useState,
} from 'react';
import type { YmDialogProps, YmTabsProps } from 'ym-design';
import { YmDialog, YmTabs } from 'ym-design';
import OrgChoiceList from './OrgChoiceList';
import PosChoiceList from './PosChoiceList';
import RoleChoiceList from './RoleChoiceList';
import type {
  ChoiceListRef,
  TChoiceStaffValue,
  TChoiceType,
  YmChoiceStaffModalProps,
} from './interface';

type TRef = {
  open: () => void;
};

const ChoiceStaff = forwardRef<TRef, YmChoiceStaffModalProps>((props, ref) => {
  const {
    prefixCls = 'ym-staff-choice',
    modalPorps = {},
    orgRequest,
    roleRequest,
    posRequest,
    requestParams,
    value,
    defaultValue,
    onlyChoicePeople = false,
    choiceBtn = 'checkbox',
    onChange,
    tabNames = ['组织架构', '角色', '岗位'],
  } = props;
  const [open, setOpen] = useState<boolean>(false);
  const [tabActiveKey, setTabActiveKey] = useState<TChoiceType>(() => {
    const tempKey: TChoiceType[] = [];
    if (typeof orgRequest === 'function') {
      tempKey.push('org');
    }
    if (typeof roleRequest === 'function') {
      tempKey.push('role');
    }
    if (typeof posRequest === 'function') {
      tempKey.push('pos');
    }
    return tempKey[0] || 'org';
  });
  const [keyWord, setKeyWord] = useState<string>();
  const orgChoiceRef = useRef<ChoiceListRef>(null);
  const roleChoiceRef = useRef<ChoiceListRef>(null);
  const posChoiceRef = useRef<ChoiceListRef>(null);
  // dialog destoryOnClose:false时，每次点击确认保存 mergeValue，如果下一次一番操作之后点击取消按钮可以复原到initialMergeValue;
  const [initialMergeValue, setInitialMergeValue] = useState<
    TChoiceStaffValue[]
  >(() => {
    if (value !== undefined) {
      return cloneDeep(value);
    } else if (defaultValue !== undefined) {
      return cloneDeep(defaultValue);
    } else {
      return [];
    }
  });

  // 初始化mergeValue值，注：用useSate包裹就意味着，组件挂载成功后就只能通过setMergeValue来更改mergeValue，尽管props变化了
  const [mergeValue, setMergeValue] = useState<TChoiceStaffValue[] | undefined>(
    () => {
      // console.log('--mergeValue--初始化--')
      if (value !== undefined) {
        return value;
      } else {
        return defaultValue;
      }
    },
  );

  // 组件挂载时(第一次)不执行
  useLayoutUpdateEffect(() => {
    setMergeValue(value);
  }, [value]);

  // modalPorps.open 控制dialog
  useEffect(() => {
    if (typeof modalPorps.open === 'boolean') {
      setOpen(modalPorps.open);
    }
  }, [modalPorps.open]);

  useImperativeHandle(ref, () => ({
    open: () => {
      setOpen(true);
    },
    close: () => {
      setOpen(false);
    },
  }));

  // 通过modalProps.open传参 open受控，否则不受控 //
  const internaleClose = (e: any) => {
    if (typeof modalPorps.open === 'boolean') {
      modalPorps.onClose?.(e);
    } else {
      setOpen(false);
    }
  };

  //取消
  const internaleCancle = (e: React.SyntheticEvent) => {
    if (typeof modalPorps.open === 'boolean') {
      modalPorps.onCancel?.(e);
    } else {
      setOpen(false);
    }
    if (!modalPorps.destroyOnClose) {
      const tempInitialValues = cloneDeep(initialMergeValue || []);
      setMergeValue(tempInitialValues);
      orgChoiceRef.current?.resetSelectedValues(
        tempInitialValues.filter((val) => val.choiceType === 'org'),
      );
      roleChoiceRef.current?.resetSelectedValues(
        tempInitialValues.filter((val) => val.choiceType === 'role'),
      );
      posChoiceRef.current?.resetSelectedValues(
        tempInitialValues.filter((val) => val.choiceType === 'pos'),
      );
    }
  };

  const choiceTabItems = useMemo(() => {
    const tempTabItems: YmTabsProps['items'] = [];
    if (typeof orgRequest === 'function') {
      tempTabItems.push({ key: 'org', label: tabNames[0] });
    }
    if (typeof roleRequest === 'function') {
      tempTabItems.push({ key: 'role', label: tabNames[1] });
    }
    if (typeof posRequest === 'function') {
      tempTabItems.push({ key: 'pos', label: tabNames[2] });
    }
    return tempTabItems;
  }, [orgRequest, roleRequest, posRequest, tabNames]);

  // modal
  const mergeModlaProps: YmDialogProps = useMemo(() => {
    const { styles = {}, ...restModalPorps } = modalPorps || {};
    if (styles.body) {
      styles.body = {
        ...styles.body,
        padding: '16px 24px',
      };
    } else {
      styles.body = { padding: '16px 24px' };
    }
    const tempModalProps = {
      destroyOnClose: false,
      title: '选择人员',
      ...restModalPorps,
      styles,
      open,
      onClose: internaleClose,
      onCancel: internaleCancle,
      onOk: (e: React.SyntheticEvent) => {
        const tempMergeValue = mergeValue || [];
        if (!restModalPorps.destroyOnClose) {
          setInitialMergeValue(cloneDeep(tempMergeValue));
        }
        if (typeof restModalPorps.onOk === 'function') {
          restModalPorps.onOk(e, tempMergeValue);
        } else {
          internaleClose(null);
          onChange?.(tempMergeValue);
        }
      },
    };
    return tempModalProps;
  }, [open, mergeValue, modalPorps]);

  //tabs
  const handleChoiceTabChange = (activeKey: string) => {
    // console.log('--handleChoiceTabChange--activeKey--:', activeKey);
    setTabActiveKey(activeKey as TChoiceType);
  };

  //搜索
  const onSearch = (value: string) => {
    // console.log('--onSearch--:', value);
    setKeyWord(value);
    if (tabActiveKey === 'org') {
      orgChoiceRef.current!.search(value);
    } else if (tabActiveKey === 'role') {
      roleChoiceRef.current!.search(value);
    } else if (tabActiveKey === 'pos') {
      posChoiceRef.current!.search(value);
    }
  };

  //删除选中
  const selItemDelete = (selectedItem: TChoiceStaffValue) => {
    if (selectedItem.choiceType === 'org') {
      orgChoiceRef.current!.delete(selectedItem);
    } else if (selectedItem.choiceType === 'role') {
      roleChoiceRef.current!.delete(selectedItem);
    } else if (selectedItem.choiceType === 'pos') {
      posChoiceRef.current!.delete(selectedItem);
    }
  };

  //当前行choice  calback
  const handleChoiceChange = (
    type: TChoiceType,
    operationType: 'add' | 'delete',
    operationItem: TChoiceStaffValue,
  ) => {
    let tempMergeVal = mergeValue || [];
    if (operationType === 'add') {
      if (choiceBtn === 'checkbox') {
        tempMergeVal.push(operationItem);
      } else {
        tempMergeVal = [operationItem];
      }
    } else if (operationType === 'delete') {
      const existIndex = tempMergeVal.findIndex(
        (valItem) => operationItem.combineId === valItem.combineId,
      );
      if (existIndex > -1) {
        tempMergeVal.splice(existIndex, 1);
      }
    }
    setMergeValue([...tempMergeVal]);
  };

  //批量choice  calback
  const handleChoiceChangeBatch = (
    type: TChoiceType,
    operationType: 'add' | 'delete',
    operationList: TChoiceStaffValue[],
  ) => {
    if (choiceBtn === 'radio') return; //单选是没有全选的
    const tempMergeVal = mergeValue || [];
    operationList.forEach((operationItem) => {
      const existIndex = tempMergeVal.findIndex(
        (valItem) => operationItem.combineId === valItem.combineId,
      );
      if (operationType === 'add' && existIndex < 0) {
        tempMergeVal.push(operationItem);
      }
      if (operationType === 'delete' && existIndex > -1) {
        tempMergeVal.splice(existIndex, 1);
      }
    });
    setMergeValue([...tempMergeVal]);
  };

  // 列表左边dom
  const getListLeftIcon = useCallback((selectedItem: TChoiceStaffValue) => {
    let tempDom: React.ReactNode;
    const { personId, hdpic, choiceType } = selectedItem;
    if (personId) {
      tempDom = <img src={hdpic || defPic} className="item_avatar" />;
    } else if (choiceType === 'org') {
      tempDom = (
        <IconFont type="icon-chengyuanyubumen" className="item_typeicon" />
      );
    } else if (choiceType === 'role') {
      tempDom = <IconFont type="icon-jue_se" className="item_typeicon" />;
    } else if (choiceType === 'pos') {
      tempDom = <IconFont type="icon-gang_wei" className="item_typeicon" />;
    }
    return tempDom;
  }, []);

  return (
    <YmDialog {...mergeModlaProps}>
      <div
        className={`${prefixCls}`}
        style={{ width: (choiceBtn === 'checkbox' ? '668' : '320') + 'px' }}
      >
        <div className={`${prefixCls}-left`}>
          <p className={`${prefixCls}-left-flag`}>选择</p>
          <div className={`${prefixCls}-left-search`}>
            <Input.Search
              placeholder="搜索"
              onSearch={onSearch}
              allowClear={true}
            />
          </div>
          {choiceTabItems.length > 1 && (
            <div className={`${prefixCls}-left-tabs`}>
              <YmTabs
                activeKey={tabActiveKey}
                items={choiceTabItems}
                onChange={handleChoiceTabChange}
                noneedTabPane={true}
                tabBarStyle={{ fontSize: '14px' }}
                tabBarGutter={24}
                tabBarListStyle={{ justifyContent: 'flex-start' }}
              />
            </div>
          )}
          <div className={`${prefixCls}-left-content`}>
            {typeof orgRequest === 'function' && (
              <div
                className={classNames('content-section', {
                  ['active']: tabActiveKey === 'org',
                })}
              >
                <OrgChoiceList
                  ref={orgChoiceRef}
                  onlyChoicePeople={onlyChoicePeople}
                  choiceBtn={choiceBtn}
                  prefixCls={prefixCls}
                  keyWord={keyWord}
                  requestParams={requestParams}
                  orgRequest={orgRequest}
                  defaultValue={mergeValue?.filter(
                    (val) => val.choiceType === 'org',
                  )}
                  onOrgChoiceChange={(operationType, operationItem) => {
                    handleChoiceChange('org', operationType, operationItem);
                  }}
                  onOrgChoiceChangeBatch={(operationType, operationList) => {
                    handleChoiceChangeBatch(
                      'org',
                      operationType,
                      operationList,
                    );
                  }}
                />
              </div>
            )}
            {typeof roleRequest === 'function' && (
              <div
                className={classNames('content-section', {
                  ['active']: tabActiveKey === 'role',
                })}
              >
                <RoleChoiceList
                  ref={roleChoiceRef}
                  onlyChoicePeople={onlyChoicePeople}
                  choiceBtn={choiceBtn}
                  prefixCls={prefixCls}
                  keyWord={keyWord}
                  requestParams={requestParams}
                  roleRequest={roleRequest}
                  defaultValue={mergeValue?.filter(
                    (val) => val.choiceType === 'role',
                  )}
                  onRoleChoiceChange={(operationType, operationItem) => {
                    handleChoiceChange('role', operationType, operationItem);
                  }}
                  onRoleChoiceChangeBatch={(operationType, operationList) => {
                    handleChoiceChangeBatch(
                      'role',
                      operationType,
                      operationList,
                    );
                  }}
                />
              </div>
            )}
            {typeof posRequest === 'function' && (
              <div
                className={classNames('content-section', {
                  ['active']: tabActiveKey === 'pos',
                })}
              >
                <PosChoiceList
                  ref={posChoiceRef}
                  onlyChoicePeople={onlyChoicePeople}
                  choiceBtn={choiceBtn}
                  prefixCls={prefixCls}
                  keyWord={keyWord}
                  requestParams={requestParams}
                  posRequest={posRequest}
                  defaultValue={mergeValue?.filter(
                    (val) => val.choiceType === 'pos',
                  )}
                  onPosChoiceChange={(operationType, operationItem) => {
                    handleChoiceChange('pos', operationType, operationItem);
                  }}
                  onPosChoiceChangeBatch={(operationType, operationList) => {
                    handleChoiceChangeBatch(
                      'pos',
                      operationType,
                      operationList,
                    );
                  }}
                />
              </div>
            )}
          </div>
        </div>
        {choiceBtn === 'checkbox' && (
          <div className={`${prefixCls}-center`}>
            <DoubleRightOutlined className={`${prefixCls}-center-arrow`} />
          </div>
        )}
        {choiceBtn === 'checkbox' && (
          <div className={`${prefixCls}-right`}>
            <p className={`${prefixCls}-right-flag`}>已选</p>
            <div className={`${prefixCls}-right-selected`}>
              <ul className={`${prefixCls}-right-selected-list`}>
                {mergeValue?.map((selItem) => (
                  <li className="list_item" key={selItem.combineId}>
                    {getListLeftIcon(selItem)}
                    <p className="item_text">
                      {selItem.personId ? (
                        <>
                          <span>{selItem.personName}</span>
                          <span>({selItem.phone})</span>
                        </>
                      ) : (
                        <span>{selItem.name}</span>
                      )}
                    </p>
                    <IconFont
                      type="icon-tishilei_cuowu"
                      className="item_deleteicon"
                      onClick={() => {
                        selItemDelete(selItem);
                      }}
                    />
                  </li>
                ))}
              </ul>
            </div>
          </div>
        )}
      </div>
    </YmDialog>
  );
});

export default ChoiceStaff;
